import 'dart:async';
import 'dart:convert';
import 'package:build/build.dart';
import 'package:glob/glob.dart';
import 'package:path/path.dart' as p;

class RouteAggregator implements Builder {
  @override
  final buildExtensions = const {
    r'$package$': ['lib/generated/route_table.dart'],
  };

  @override
  Future<void> build(BuildStep buildStep) async {
    print('⚡ RouteAggregator 开始执行');

    try {
      final routes = <Map<String, dynamic>>[];
      final imports = <String>{};
      final assets = buildStep.findAssets(Glob('**/*.route.json'));

      await for (final input in assets) {
        print('📂 处理路由文件: ${input.path}');
        try {
          String content = await buildStep.readAsString(input);

          // 移除JSON文件中的注释
          content =
              content
                  .replaceAll(RegExp(r'^\s*//.*$', multiLine: true), '')
                  .trim();

          if (content.isEmpty) {
            print('⚠️ 空文件跳过: ${input.path}');
            continue;
          }

          final data = json.decode(content) as Map<String, dynamic>;
          routes.add(data);
          (data['imports'] as List).cast<String>().forEach(imports.add);
          print('✅ 成功加载路由: ${data['routeName']}');
        } catch (e, stack) {
          print('''
            ❌ 解析错误: ${input.path}
            错误: $e
            堆栈: $stack
            ''');
          rethrow;
        }
      }

      if (routes.isEmpty) {
        print('''
          ⛔ 未找到有效路由配置!
          请检查:
          1. 确保至少有一个类使用了 @GetXRoute 注解
          2. 检查 build.yaml 的 generate_for 配置
          3. 尝试运行: flutter pub run build_runner clean
        ''');
        return;
      }

      // 生成最终路由表
      await _generateRouteTable(buildStep, routes, imports);
    } catch (e) {
      print('‼️ 聚合器发生致命错误: ${e.toString()}');
      rethrow;
    }
  }

  Future<void> _generateRouteTable(
    BuildStep buildStep,
    List<Map<String, dynamic>> routes,
    Set<String> imports,
  ) async {
    final buffer =
        StringBuffer()
          ..writeln("// GENERATED CODE - DO NOT MODIFY BY HAND")
          ..writeln("import 'package:get/get.dart';");

    // 添加排序后的imports
    for (final import in imports.toList()..sort()) {
      buffer.writeln("import '$import';");
    }

    buffer.writeln("\nclass RouteTable {");

    // 生成公开的路由常量（全大写命名）
    buffer.writeln("  // 路由名称常量");
    for (final route in routes) {
      final constName = _routeToConstName(route['routeName'] as String);
      buffer.writeln(
        "  static const String $constName = '${route['routeName']}';",
      );
    }

    // 生成GetPages
    buffer.writeln("\n  static final List<GetPage> pages = [");
    for (final route in routes) {
      _generateGetPage(buffer, route);
    }
    buffer.writeln("  ];");
    buffer.writeln("}");

    // 写入文件
    final outputId = AssetId(
      buildStep.inputId.package,
      p.join('lib', 'generated', 'route_table.dart'),
    );
    await buildStep.writeAsString(outputId, buffer.toString());
    print('🎉 成功生成路由表: ${outputId.path}');
  }

  void _generateGetPage(StringBuffer buffer, Map<String, dynamic> route) {
    final constName = _routeToConstName(route['routeName'] as String);

    buffer.writeln("    GetPage(");
    buffer.writeln("      name: $constName,");
    buffer.writeln("      page: () => ${route['className']}(),");

    // 修改这里：添加括号实例化
    if (route['binding'] != null) {
      buffer.writeln("      binding: ${route['binding']}(),"); // 注意这里的()
    }

    // 处理middlewares
    if ((route['middlewares'] as List).isNotEmpty) {
      buffer.writeln("      middlewares: [");
      for (final m in route['middlewares'] as List) {
        buffer.writeln("        $m(),");
      }
      buffer.writeln("      ],");
    }

    buffer.writeln("    ),");
  }

  String _routeToConstName(String routeName) {
    return routeName
        .replaceAll('/', '_') // 将/转为_
        .replaceAll(RegExp(r'[^a-zA-Z0-9_]'), '') // 移除非字母数字字符
        .replaceAll(RegExp(r'_+'), '_') // 合并多个_
        .replaceAll(RegExp(r'^_|_$'), '') // 去除首尾_
        .toUpperCase(); // 转为全大写
  }
}
